﻿namespace DungeonGenerator
{
    using System;
    using System.Collections.Generic;
    using System.Windows;

    /// Having direction AND magnitude!
    public struct Vector2d
    {
        public int x;
        public int y;
        public int xMod;
        public int yMod;

        public Vector2d RandomizeWithinMods(int minMod, IRandomize rnd)
        {
            var nextXmod = this.xMod > 0 ? rnd.Next(minMod, Math.Max(minMod, this.xMod)) : rnd.Next(minMod * -1, Math.Min(this.xMod, minMod * -1));
            var nextYMod = this.yMod > 0 ? rnd.Next(minMod, Math.Max(minMod, this.yMod)) : rnd.Next(minMod * -1, Math.Min(this.yMod, minMod * -1));
            return new Vector2d { x = this.x, y = this.y, xMod = nextXmod, yMod = nextYMod };
        }

        public IEnumerable<PointI> WalkX()
        {
            //if xMod is positive we start at x and walk until xMod
            //if xMod is negative we start at xMod and walk until x
            var destination = this.x + this.xMod;
            for (var i = Math.Min(this.x, destination); i < Math.Max(this.x, destination); i++)
            {
                var v = new PointI() { X = i, Y = this.y };
                yield return v;
            }
        }

        public IEnumerable<PointI> WalkY()
        {
            //if xMod is positive we start at x and walk until xMod
            //if xMod is negative we start at xMod and walk until x
            var destination = this.y + this.yMod;
            for (var i = Math.Min(this.y, destination); i < Math.Max(this.y, destination); i++)
            {
                var v = new PointI() { X = this.x, Y = i };
                yield return v;
            }
        }

        public IEnumerable<PointI> Walk()
        {
            foreach (var i in this.WalkX())
                foreach (var j in this.WalkY())
                {
                    yield return new PointI { X = i.X, Y = j.Y };
                }

        }

        public Rect GetRect()
        {
            return new Rect(Math.Min(x,x+xMod), Math.Min(y,y+yMod), Math.Abs(xMod), Math.Abs(yMod));
        }

        public PointI GetOrigin()
        {
            return new PointI { X = this.x, Y = this.y };
        }

    }
}